using System;

namespace ExcelTemplateEngine.Exceptions
{
    /// <summary>
    /// 模板解析异常
    /// </summary>
    public class TemplateParseException : TemplateEngineException
    {
        public string? TemplatePath { get; }
        public string? CellAddress { get; }
        public string? TemplateContent { get; }
        
        public TemplateParseException(string message, string? templatePath = null, string? cellAddress = null, string? templateContent = null)
            : base("TEMPLATE_PARSE_ERROR", message)
        {
            TemplatePath = templatePath;
            CellAddress = cellAddress;
            TemplateContent = templateContent;
            
            if (!string.IsNullOrEmpty(templatePath))
                AddContext("TemplatePath", templatePath!);
            if (!string.IsNullOrEmpty(cellAddress))
                AddContext("CellAddress", cellAddress!);
            if (!string.IsNullOrEmpty(templateContent))
                AddContext("TemplateContent", templateContent!);
        }
    }
    
    /// <summary>
    /// 数据源异常
    /// </summary>
    public class DataSourceException : TemplateEngineException
    {
        public string? DataSourceName { get; }
        
        public DataSourceException(string message, string? dataSourceName = null, Exception? innerException = null)
            : base("DATA_SOURCE_ERROR", message, innerException)
        {
            DataSourceName = dataSourceName;
            if (!string.IsNullOrEmpty(dataSourceName))
                AddContext("DataSourceName", dataSourceName!);
        }
    }
    
    /// <summary>
    /// 表达式计算异常
    /// </summary>
    public class ExpressionEvaluationException : TemplateEngineException
    {
        public string? Expression { get; }
        public string? CellAddress { get; }
        
        public ExpressionEvaluationException(string message, string? expression = null, string? cellAddress = null, Exception? innerException = null)
            : base("EXPRESSION_EVAL_ERROR", message, innerException)
        {
            Expression = expression;
            CellAddress = cellAddress;
            
            if (!string.IsNullOrEmpty(expression))
                AddContext("Expression", expression!);
            if (!string.IsNullOrEmpty(cellAddress))
                AddContext("CellAddress", cellAddress!);
        }
    }
    
    /// <summary>
    /// Excel操作异常
    /// </summary>
    public class ExcelOperationException : TemplateEngineException
    {
        public string? Operation { get; }
        public string? CellAddress { get; }
        
        public ExcelOperationException(string message, string? operation = null, string? cellAddress = null, Exception? innerException = null)
            : base("EXCEL_OPERATION_ERROR", message, innerException)
        {
            Operation = operation;
            CellAddress = cellAddress;
            
            if (!string.IsNullOrEmpty(operation))
                AddContext("Operation", operation!);
            if (!string.IsNullOrEmpty(cellAddress))
                AddContext("CellAddress", cellAddress!);
        }
    }
    
    /// <summary>
    /// 配置异常
    /// </summary>
    public class ConfigurationException : TemplateEngineException
    {
        public string? ConfigurationKey { get; }
        
        public ConfigurationException(string message, string? configurationKey = null, Exception? innerException = null)
            : base("CONFIGURATION_ERROR", message, innerException)
        {
            ConfigurationKey = configurationKey;
            if (!string.IsNullOrEmpty(configurationKey))
                AddContext("ConfigurationKey", configurationKey!);
        }
    }
    
    /// <summary>
    /// 资源限制异常
    /// </summary>
    public class ResourceLimitException : TemplateEngineException
    {
        public string ResourceType { get; }
        public long CurrentValue { get; }
        public long LimitValue { get; }
        
        public ResourceLimitException(string message, string resourceType, long currentValue, long limitValue)
            : base("RESOURCE_LIMIT_ERROR", message)
        {
            ResourceType = resourceType;
            CurrentValue = currentValue;
            LimitValue = limitValue;
            
            AddContext("ResourceType", resourceType);
            AddContext("CurrentValue", currentValue);
            AddContext("LimitValue", limitValue);
        }
    }
    
    /// <summary>
    /// 通用模板引擎异常
    /// </summary>
    public class GeneralTemplateEngineException : TemplateEngineException
    {
        public GeneralTemplateEngineException(string message, Exception? innerException = null)
            : base("GENERAL_ERROR", message, innerException)
        {
        }
    }
}